package com.lck.blogmanager.service.impl;

import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.jwt.JWTUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lck.blogmanager.Enum.CommonConstant;
import com.lck.blogmanager.Enum.CommonEnum;
import com.lck.blogmanager.Enum.UserStatusEnum;
import com.lck.blogmanager.entity.UserEntity;
import com.lck.blogmanager.exception.BusinessException;
import com.lck.blogmanager.mapper.UserMapper;
import com.lck.blogmanager.req.*;
import com.lck.blogmanager.res.UserInfoPageRes;
import com.lck.blogmanager.service.UserService;
import com.lck.blogmanager.util.CacheTool;
import com.lck.blogmanager.util.PasswordEncodeUtil;
import com.lck.blogmanager.util.SecurityUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

import static com.lck.blogmanager.Enum.CommonConstant.WINDOWS_PATH;

/**
 * @author wyq
 * @version v1.0.0
 * @explain
 * @date 2024/4/7 17:18
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, UserEntity> implements UserService {

    private final CacheTool cacheTool;

    @Override
    public Map<String,String> userLogin(UserLoginReq req) {
        String telephone = req.getTelephone();
        String unCode = req.getPassword();
        String enCode = PasswordEncodeUtil.passwordEncode(unCode, CommonConstant.PASSWORD_SALT);
        QueryWrapper<UserEntity> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(UserEntity::getTelephone,telephone)
                .eq(UserEntity::getPassword,enCode);
        UserEntity entity = this.getBaseMapper().selectOne(wrapper);
        if(ObjectUtil.isNull(entity)){
            throw new BusinessException("用户手机号或者密码错误");
        }
        if(entity.getStatus().equals(CommonEnum.NO.getValue())){
            throw new BusinessException("用户已被禁用");
        }
        Map<String,Object> payloads = new HashMap<>();
        payloads.put("userId",entity.getId());
        long l = System.currentTimeMillis() / 100 + CommonConstant.TOKEN_VALID_SECONDS;
        System.out.println(l);
        payloads.put("exp",l);
        String token = JWTUtil.createToken(payloads, CommonConstant.TOKEN_SIGN_KEY.getBytes());
        //加入缓存
        cacheTool.add(CommonConstant.TOKEN_PREFIX+entity.getId(),token);
        Map<String,String> map = new HashMap<>();
        map.put("token",token);
        map.put("img_path",entity.getImgPath());
        return map;
    }

    @Override
    public Page<UserInfoPageRes> userInfoPage(UserInfoPageReq req) {
        Page page = new Page(req.getPageNum(),req.getPageSize());
        Page<UserInfoPageRes> res = this.getBaseMapper().userInfoPage(req,page);
        return res;
    }

    @Override
    public Integer userRegister(UserRegisterReq req) {
        QueryWrapper<UserEntity> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(UserEntity::getTelephone,req.getTelephone());
        Long count = this.getBaseMapper().selectCount(wrapper);
        if(count>0){
            throw new BusinessException("该手机号已存在");
        }

        UserEntity entity = new UserEntity();
        entity.setName(req.getName());
        entity.setNickName(req.getNickName());
        entity.setPassword(PasswordEncodeUtil.passwordEncode(req.getPassword(), CommonConstant.PASSWORD_SALT));
        entity.setTelephone(req.getTelephone());
        entity.setImgPath(req.getUserId());
        entity.setStatus(UserStatusEnum.NORMAL.getValue());
        //其它参数的填充
        this.getBaseMapper().insert(entity);
        return entity.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void uploadPic(MultipartFile file) {
        Integer userId = SecurityUtils.getUserId();

        //如果文件为空 报错
        if (file.isEmpty()) {
            throw new BusinessException("文件为空");
        }
        try {
            //获取项目当前路径
//            String url = "D:\\ideaProject";
            String url = WINDOWS_PATH;
            Path imgPath = Paths.get(url,"img");
            //获取文件字节流文件
            byte[] bytes = file.getBytes();
            //文件id
            String randomString = UUID.randomUUID().toString();
            // 仅保留前 5 个字符作为随机字符串
            String newRan = randomString.substring(0, 5);
            String fileName = "userId"+newRan+"-"+userId+".jpg";
            // 构建保存文件的路径
            Path filePath = imgPath.resolve(fileName);
            // 将文件保存到本地
            Files.write(filePath, bytes);
            //更新数据库记录
            UserEntity user = this.getBaseMapper().selectById(userId);
            user.setImgPath(fileName);
            this.saveOrUpdate(user);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public UserEntity getUserDetail(Integer userId) {
        return this.getBaseMapper().selectById(userId);
    }

    @Override
    public void changeUserStatus(ChangeUserStatusReq req) {
        QueryWrapper<UserEntity> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(UserEntity::getId,req.getUserId());
        UserEntity entity = this.getBaseMapper().selectOne(wrapper);
        if(ObjectUtil.isNull(entity)){
            throw new BusinessException("查询不到该用户，请检查userId");
        }
        if(CommonEnum.YES.getValue().equals(entity.getStatus())){
            entity.setStatus(CommonEnum.NO.getValue());
        }else {
            entity.setStatus(CommonEnum.YES.getValue());
        }
        int i = this.getBaseMapper().updateById(entity);
        if(i<1){
            throw new BusinessException("更改用户状态失败");
        }
    }

    @Override
    public void resetPassword(Integer userId) {
        String encode = PasswordEncodeUtil.passwordEncode(CommonConstant.NORMAL_PASSWORD,CommonConstant.PASSWORD_SALT);
        UserEntity entity = new UserEntity();
        entity.setId(userId);
        entity.setPassword(encode);
        int i = this.getBaseMapper().updateById(entity);
        if(i!=1){
            throw new BusinessException("用户不存在，重新确定用户id");
        }
    }

    @Override
    public void updatePassword(UpdatePasswordReq req) {
        Integer userId = SecurityUtils.getUserId();
        UserEntity user = this.getById(userId);
        user.setPassword(PasswordEncodeUtil.passwordEncode(req.getNewPwd(),CommonConstant.PASSWORD_SALT));
        saveOrUpdate(user);
    }

    @Override
    public UserEntity infoDetail() {
        Integer userId = SecurityUtils.getUserId();
        UserEntity user = this.getById(userId);
        return user;
    }

    @Override
    public String addPic(MultipartFile file) {
        String fileName = null;
        //如果文件为空 报错
        if (file.isEmpty()) {
            throw new BusinessException("文件为空");
        }
        try {
            //获取项目当前路径
//            String url = "D:\\ideaProject";
            String url = WINDOWS_PATH;
            Path imgPath = Paths.get(url,"img");
            //获取文件字节流文件
            byte[] bytes = file.getBytes();
            //文件id
            String randomString = UUID.randomUUID().toString();
            // 仅保留前 5 个字符作为随机字符串
            String newRan = randomString.substring(0, 8);
            fileName = "userId"+"-"+newRan+".jpg";
            // 构建保存文件的路径
            Path filePath = imgPath.resolve(fileName);
            // 将文件保存到本地
            Files.write(filePath, bytes);
            //更新数据库记录
        } catch (Exception e) {
            e.printStackTrace();
        }
        return fileName;
    }

}
